package com.mallcai.bigdata.ladon.controller.report;

import com.cake.bigdata.starter.exception.category.BusinessException;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Joiner;
import com.mallcai.bigdata.ladon.client.param.ReportQueryParam;
import com.mallcai.bigdata.ladon.client.service.IReportDataQueryService;
import com.mallcai.bigdata.ladon.client.vo.ReportDataVO;
import com.mallcai.bigdata.ladon.common.SessionThreadLocal;
import com.mallcai.bigdata.ladon.controller.report.form.ReportForm;
import com.mallcai.bigdata.ladon.controller.report.form.ReportQueryForm;
import com.mallcai.bigdata.ladon.controller.report.form.ReportSqlForm;
import com.mallcai.bigdata.ladon.controller.system.form.RoleForm;
import com.mallcai.bigdata.ladon.dpl.entity.report.QueryField;
import com.mallcai.bigdata.ladon.dpl.entity.report.Report;
import com.mallcai.bigdata.ladon.dpl.entity.report.ReportColumn;
import com.mallcai.bigdata.ladon.dpl.entity.report.ReportSql;
import com.mallcai.bigdata.ladon.dpl.vo.DataType;
import com.mallcai.bigdata.ladon.dpl.vo.QueryFieldType;
import com.mallcai.bigdata.ladon.dpl.vo.ReportType;
import com.mallcai.bigdata.ladon.service.report.IReportService;
import com.mallcai.bigdata.ladon.utils.CollectionUtils;
import com.mallcai.bigdata.ladon.vo.MyPageInfo;
import com.mallcai.bigdata.ladon.vo.Pair;
import com.mallcai.bigdata.ladon.vo.args.QueryArg;
import com.mallcai.bigdata.ladon.vo.system.TreeNodeVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * 报表设计
 * Created by oneape<oneape15@163.com>
 * Created 2019-07-09 14:16.
 * Modify:
 */
@Slf4j
@RequestMapping("/report/design")
@RestController
public class ReportController {

    @Autowired
    private IReportService iReportService;
    @Autowired
    private IReportDataQueryService iReportDataQueryService;

    @RequestMapping("/getByPage")
    public MyPageInfo getByPage(@RequestBody @Validated RoleForm form) {
        PageHelper.startPage(form.getCurrentPage(), form.getPageSize());
        List<Report> reports = iReportService.getByParams(form.getParams());
        PageInfo<Report> pageInfo = new PageInfo<>(reports);

        return new MyPageInfo<>(pageInfo);
    }

    @RequestMapping("/add")
    public String addReport(@RequestBody @Validated(value = ReportForm.AddCheck.class) ReportForm form) {
        Report report = form.toEntity();

        List<Long> groupIds = form.getGroupIds();
        if (groupIds == null || groupIds.size() == 0) {
            throw new BusinessException("所属报表组必必须选择");
        }
        List<Integer> types = form.getType();
        if (types == null || types.size() == 0) {
            throw new BusinessException("报表类型不能为空");
        }
        report.setType(Joiner.on(",").join(types));
        int status = iReportService.addReport(report, groupIds);
        if (status <= 0) {
            throw new BusinessException("添加报表失败");
        }
        return "添加报表成功";
    }

    @RequestMapping("/edit")
    public String editReport(@RequestBody @Validated(value = ReportForm.EditCheck.class) ReportForm form) {
        Report report = form.toEntity();

        List<Long> groupIds = form.getGroupIds();
        if (groupIds == null || groupIds.size() == 0) {
            throw new BusinessException("所属报表组必必须选择");
        }

        int status = iReportService.editReport(report, groupIds);
        if (status <= 0) {
            throw new BusinessException("修改报表失败");
        }

        return "修改报表成功";
    }

    @RequestMapping("/del")
    public String delReport(@RequestBody @Validated(value = ReportForm.IdCheck.class) ReportForm form) {
        Report report = form.toEntity();
        int status = iReportService.delReport(report);
        if (status <= 0) {
            throw new BusinessException("删除报表失败");
        }
        return "删除报表成功";
    }

    @RequestMapping("/copy")
    public String copyReport(@RequestBody @Validated(value = ReportForm.IdCheck.class) ReportForm form) {
        int status = iReportService.copyReport(form.getReportId());
        if (status <= 0) {
            throw new BusinessException("复制报表失败");
        }
        return "复制报表成功";
    }

    /**
     * 获取报表类型
     *
     * @return ApiResult
     */
    @RequestMapping("/types")
    public List<TreeNodeVo> getReportTypes() {
        List<TreeNodeVo> pairs = new ArrayList<>();
        for (ReportType rt : ReportType.values()) {
            pairs.add(new TreeNodeVo(rt.getCode() + "", rt.getDesc()));
        }
        return pairs;
    }

    /**
     * 获取数据类型
     *
     * @return ApiResult
     */
    @RequestMapping("/dataTypes")
    public List<TreeNodeVo> getDataTypes() {
        List<TreeNodeVo> pairs = new ArrayList<>();
        pairs.add(new TreeNodeVo(DataType.STRING.getCode(), DataType.STRING.getDesc()));
        pairs.add(new TreeNodeVo(DataType.INTEGER.getCode(), DataType.INTEGER.getDesc()));
        pairs.add(new TreeNodeVo(DataType.LONG.getCode(), DataType.LONG.getDesc()));
        pairs.add(new TreeNodeVo(DataType.DOUBLE.getCode(), DataType.DOUBLE.getDesc()));
        pairs.add(new TreeNodeVo(DataType.DATE.getCode(), "日期(yyyy-MM-dd)"));
        pairs.add(new TreeNodeVo(DataType.DATETIME.getCode(), "日期时间(yyyy-MM-dd HH:mm:ss)"));
        pairs.add(new TreeNodeVo(DataType.TIMESTAMP.getCode(), DataType.TIMESTAMP.getDesc()));

        return pairs;
    }

    /**
     * 获取查询字段类型
     *
     * @return ApiResult
     */
    @RequestMapping("/fieldTypes")
    public List<Pair> getQueryFieldTypes() {
        List<Pair> pairs = new ArrayList<>();
        for (QueryFieldType qft : QueryFieldType.values()) {
            pairs.add(new Pair<>(qft.getCode(), qft.getDesc()));
        }
        return pairs;
    }

    /**
     * 拉冬后台,报表查询
     *
     * @return ApiResult
     */
    @RequestMapping("/queryData")
    public ReportDataVO queryData(@RequestBody @Validated(value = ReportQueryForm.QueryCheck.class) ReportQueryForm form) {
        iReportDataQueryService.parseParamName(form.getReportCode());
        Map<String, Object> allParams = new HashMap<>(8);
        if (CollectionUtils.isNotEmpty(form.getParams())) {
            allParams.putAll(form.getParams());
        }
        ReportQueryParam reportQueryParam = new ReportQueryParam("ladon", form.getReportCode());
        reportQueryParam.setNeedRunSql(form.getShowSql()==1);
        reportQueryParam.setUserId(SessionThreadLocal.getUserId());
        return iReportDataQueryService.queryData(reportQueryParam,allParams);
    }

    /**
     * SQL信息保存
     *
     * @return ApiResult
     */
    @RequestMapping("/saveSql")
    public String saveSqlInfo(@RequestBody @Validated(value = ReportSqlForm.SaveCheck.class) ReportSqlForm form) {
        ReportSql reportSql = form.toEntity();

        int status = iReportService.saveReportSql(form.getReportId(), reportSql);
        if (status <= 0) {
            throw new BusinessException("SQL信息保存失败");
        }
        return "SQL信息保存成功";
    }

    /**
     * 根据SQL主键获取详细信息
     *
     * @param form ReportSqlForm
     * @return ApiResult
     */
    @RequestMapping("/getSqlInfoById")
    public ReportSql getSqlInfoById(@RequestBody @Validated(value = ReportSqlForm.IdCheck.class) ReportSqlForm form) {
        return iReportService.getSqlInfoById(form.getSqlId());
    }

    /**
     * 保存查询参数信息
     *
     * @param form ReportForm
     * @return ApiResult
     */
    @RequestMapping("/saveQueryFields")
    public String saveQueryField(@RequestBody @Validated(value = ReportForm.IdCheck.class) ReportForm form) {
        int status = iReportService.saveQueryFields(form.getReportId(), form.getQueryFields());
        if (status <= 0) {
            throw new BusinessException("查询参数保存失败");
        }
        return "查询参数保存成功";
    }

    /**
     * 获取报表查询参数信息
     *
     * @param form ReportForm
     * @return ApiResult
     */
    @RequestMapping("/getQueryFieldsByReportId")
    public List<QueryField> getQueryFieldsByReportId(@RequestBody @Validated(value = ReportForm.IdCheck.class) ReportForm form) {
        return iReportService.getQueryFields(form.getReportId());
    }

    /**
     * 查询报表详情
     *
     * @param form ReportForm
     * @return ApiResult
     */
    @RequestMapping("/getDetailById")
    public Map<String, Object> getDetailById(@RequestBody @Validated(value = ReportForm.IdCheck.class) ReportForm form) {
        List<QueryArg> args = iReportService.getReportQueryArgs(form.getReportId());
        Report report = iReportService.getById(form.getReportId());
        Map<String, Object> ret = new HashMap<>();
        ret.put("queryArgs", args);
        ret.put("report", report);
        return ret;
    }

    /**
     * 保存报表字段信息
     *
     * @param form ReportForm
     * @return ApiResult
     */
    @RequestMapping("/saveReportColumns")
    public String saveReportColumns(@RequestBody @Validated(value = ReportForm.IdCheck.class) ReportForm form) {
        int status = iReportService.saveReportColumns(form.getReportId(), form.getReportColumns());
        if (status <= 0) {
            throw new BusinessException("报表字段信息保存失败");
        }
        return "报表字段信息保存成功";
    }

    /**
     * 获取报表字段信息
     *
     * @param form ReportForm
     * @return ApiResult
     */
    @RequestMapping("/getReportColumnsByReportId")
    public List<ReportColumn> getReportColumnsByReportId(@RequestBody @Validated(value = ReportForm.IdCheck.class) ReportForm form) {
        return iReportService.getReportColumns(form.getReportId());
    }

    /**
     * 获取报表树型结构(报表组与报表结合)
     *
     * @param form ReportForm
     * @return ApiResult
     */
    @RequestMapping("/reportTree")
    public List<TreeNodeVo> getReportTree(@RequestBody @Validated ReportForm form) {
        return iReportService.getReportTree(form.getSimpleReport(), form.getFilterIds(), form.getFixOption());
    }

    /**
     * 获取全部报表的code以及name
     * @return ApiResult
     */
    @RequestMapping("/getReportCodeAndName")
    public List<Report> getReportCodeAndName() {
        return iReportService.getReportCodeAndName();
    }
}
